#include "stdafx.h"
#include "TaskPoolImpl.h"
#include "ThreadImpl.h"

TaskPoolImpl::TaskPoolImpl() :
thread_cnt_(0),
task_queue_(NULL),
thread_vec_(0)
{
	memset(&stat_, 0, sizeof(stat_));
}

TaskPoolImpl::~TaskPoolImpl()
{
	if(task_queue_)
		delete task_queue_;
	for(THREAD_VECTOR::iterator iter = thread_vec_.begin(); iter != thread_vec_.end(); iter++)
		(*iter)->destroy();
}

TaskPoolImpl * TaskPoolImpl::create(int trd_cnt)
{
	TaskPoolImpl *inst = new TaskPoolImpl();
	if(inst)
	{
		if(!inst->init(trd_cnt))
		{
			inst->destroy();
			inst = NULL;
		}
	}
	return inst;
}

bool TaskPoolImpl::init(int trd_cnt)
{
	if(trd_cnt == 0)
		return false;
	task_queue_ = new TaskQueueSync();
	if(!task_queue_)
		return false;
	for(int i = 0; i < trd_cnt; i++)
	{
		Thread *p = ThreadImpl::create(task_queue_);
		if(!p)
			break;
		thread_vec_.push_back(p);
	}

	if(thread_vec_.size() != trd_cnt)
	{
		for(THREAD_VECTOR::iterator iter = thread_vec_.begin(); iter != thread_vec_.end(); iter++)
			(*iter)->destroy();
		thread_vec_.clear();
		return false;
	}
	return true;
}

void TaskPoolImpl::destroy()
{
	delete this;
}

bool TaskPoolImpl::set_task(Task *task)
{
	if(!task)
		return false;
	if(task_queue_->set_task(task))
	{
		stat_.total_task_++;
		return true;
	}
	return false;
}

bool TaskPoolImpl::get_stat(TaskPoolStat *stat)
{
	if(!stat)
		return false;
	query_stat();
	memcpy(stat, &stat_, sizeof(stat));
	return true;
}

bool TaskPoolImpl::complete()
{
	query_stat();
	return stat_.completed_;
}

void TaskPoolImpl::query_stat()
{
	stat_.completed_ = true;
	stat_.complete_task_ = 0;
	stat_.left_task_ = stat_.total_task_;

	for(THREAD_VECTOR::iterator iter = thread_vec_.begin(); iter != thread_vec_.end(); iter++)
	{
		stat_.complete_task_ += (*iter)->get_complete();
		stat_.left_task_ -= (*iter)->get_complete();
		stat_.completed_ = stat_.completed_ && ((*iter)->get_status() == Thread::WAITING);
	}
}